/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainWindow.java
 *
 * Created on 04.11.2010, 08:53:39
 */
package gui;

import basic.CORE;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTable.PrintMode;
import logic.Alteration;
import logic.SaveCSV;
import logic.SaveProp;
import sql.UpdateTable;

/**
 *
 * @author Guybrush
 */
public class MainWin extends JFrame /*implements TableModelListener*/ {

    //Konstruktor
    public MainWin(CORE aThis) {
        this.core = aThis;  //Instanzirung von CORE
        //Beendet das Programm korrekt beim Schliessen des Fensters-------------
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                closeProgram();
            }
        });
        //----------------------------------------------------------------------
        initComponents();   //Aufbau der GUI (generiert)
        //Vergrößert das Fenster auf die Desktopauflösung des Benutzers---------
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        this.setSize(screenSize.width - 40, screenSize.height - 40);
        setLocationRelativeTo(null);
        //----------------------------------------------------------------------
        this.validate();    //Überprüft das Layout der Komponenten
        initData();         //Aufbau der GUI (manueller Teil der Methoden/GUI)
    }

    //Beginn des generierten Code
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lStatus = new javax.swing.JLabel();
        pEdit = new javax.swing.JPanel();
        tfEdit = new javax.swing.JTextField();
        lCloseEdit = new javax.swing.JLabel();
        maintp = new javax.swing.JTabbedPane();
        mb = new javax.swing.JMenuBar();
        m1 = new javax.swing.JMenu();
        miSave = new javax.swing.JMenuItem();
        miSaveCsv = new javax.swing.JMenuItem();
        miPrint = new javax.swing.JMenuItem();
        m1s1 = new javax.swing.JPopupMenu.Separator();
        miExit = new javax.swing.JMenuItem();
        m2 = new javax.swing.JMenu();
        miUndo = new javax.swing.JMenuItem();
        miRedo = new javax.swing.JMenuItem();
        m3 = new javax.swing.JMenu();
        miConfigFile = new javax.swing.JMenuItem();
        miAbout = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("HC-Media Database Administration Utility");
        setBackground(new java.awt.Color(15, 30, 70));

        lStatus.setText("Datenbank '"+ core.getVariable().getDbname() +"' erfolgreich geladen...");
        lStatus.setInheritsPopupMenu(false);

        tfEdit.setFont(new java.awt.Font("Verdana", 0, 14));
        tfEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                tfEditActionPerformed(evt);
            }
        });

        lCloseEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pics/close.png"))); // NOI18N
        lCloseEdit.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                lCloseEditMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout pEditLayout = new javax.swing.GroupLayout(pEdit);
        pEdit.setLayout(pEditLayout);
        pEditLayout.setHorizontalGroup(
            pEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pEditLayout.createSequentialGroup()
                .addComponent(tfEdit, javax.swing.GroupLayout.DEFAULT_SIZE, 474, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lCloseEdit))
        );
        pEditLayout.setVerticalGroup(
            pEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(tfEdit, javax.swing.GroupLayout.DEFAULT_SIZE, 32, Short.MAX_VALUE)
            .addComponent(lCloseEdit, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        maintp.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        maintp.setTabPlacement(javax.swing.JTabbedPane.LEFT);
        maintp.setAutoscrolls(true);
        maintp.setInheritsPopupMenu(true);

        m1.setText("Datei");

        miSave.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        miSave.setText("Speichern");
        miSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miSaveActionPerformed(evt);
            }
        });
        m1.add(miSave);

        miSaveCsv.setText("Speichern als CSV");
        miSaveCsv.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miSaveCsvActionPerformed(evt);
            }
        });
        m1.add(miSaveCsv);

        miPrint.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK));
        miPrint.setText("Tabelle drucken...");
        miPrint.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miPrintActionPerformed(evt);
            }
        });
        m1.add(miPrint);
        m1.add(m1s1);

        miExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
        miExit.setText("Beenden");
        miExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miExitActionPerformed(evt);
            }
        });
        m1.add(miExit);

        mb.add(m1);

        m2.setText("Bearbeiten");

        miUndo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.event.InputEvent.CTRL_MASK));
        miUndo.setText("Rückgängig");
        miUndo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miUndoActionPerformed(evt);
            }
        });
        m2.add(miUndo);

        miRedo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Y, java.awt.event.InputEvent.CTRL_MASK));
        miRedo.setText("Wiederholen");
        miRedo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miRedoActionPerformed(evt);
            }
        });
        m2.add(miRedo);

        mb.add(m2);

        m3.setText("Extras");

        miConfigFile.setText("Logindaten speichern");
        miConfigFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miConfigFileActionPerformed(evt);
            }
        });
        m3.add(miConfigFile);

        miAbout.setText("Über HC-Connect");
        miAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miAboutActionPerformed(evt);
            }
        });
        m3.add(miAbout);

        mb.add(m3);

        setJMenuBar(mb);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(lStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 510, Short.MAX_VALUE)
            .addComponent(pEdit, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(maintp, javax.swing.GroupLayout.DEFAULT_SIZE, 510, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(pEdit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(maintp, javax.swing.GroupLayout.DEFAULT_SIZE, 228, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lStatus))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    //Ende

    //Events für GUI Komponenten
    private void miSaveCsvActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miSaveCsvActionPerformed
        saveToCSV();
    }//GEN-LAST:event_miSaveCsvActionPerformed

    private void miPrintActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miPrintActionPerformed
        printTest(maintp.getSelectedIndex());
    }//GEN-LAST:event_miPrintActionPerformed

    private void miExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miExitActionPerformed
        closeProgram();
    }//GEN-LAST:event_miExitActionPerformed

    private void lCloseEditMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lCloseEditMouseClicked
        pEdit.setVisible(false);
        tfEdit.setText("");
        target.setEnabled(true);
        target.setFocusable(true);
        maintp.setEnabled(true);
        maintp.setFocusable(true);
}//GEN-LAST:event_lCloseEditMouseClicked

    private void miAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miAboutActionPerformed
        JDialog f = new About(new JFrame());
        f.setVisible(true);
    }//GEN-LAST:event_miAboutActionPerformed

    private void miSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miSaveActionPerformed
        saveToDB();
    }//GEN-LAST:event_miSaveActionPerformed

    private void tfEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tfEditActionPerformed
        modify();
        pEdit.setVisible(false);
        tfEdit.setText("");
        target.setEnabled(true);
        target.setFocusable(true);
        maintp.setEnabled(true);
        maintp.setFocusable(true);
    }//GEN-LAST:event_tfEditActionPerformed

    private void miUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miUndoActionPerformed
        miRedo.setEnabled(true);
        doUndo();
    }//GEN-LAST:event_miUndoActionPerformed

    private void miRedoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miRedoActionPerformed
        doRedo();
    }//GEN-LAST:event_miRedoActionPerformed

    private void miConfigFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miConfigFileActionPerformed
        SaveProp prop = new SaveProp(core.getVariable());
    }//GEN-LAST:event_miConfigFileActionPerformed
    //Ende
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel lCloseEdit;
    private javax.swing.JLabel lStatus;
    private javax.swing.JMenu m1;
    private javax.swing.JPopupMenu.Separator m1s1;
    private javax.swing.JMenu m2;
    private javax.swing.JMenu m3;
    private javax.swing.JTabbedPane maintp;
    private javax.swing.JMenuBar mb;
    private javax.swing.JMenuItem miAbout;
    private javax.swing.JMenuItem miConfigFile;
    private javax.swing.JMenuItem miExit;
    private javax.swing.JMenuItem miPrint;
    private javax.swing.JMenuItem miRedo;
    private javax.swing.JMenuItem miSave;
    private javax.swing.JMenuItem miSaveCsv;
    private javax.swing.JMenuItem miUndo;
    private javax.swing.JPanel pEdit;
    private javax.swing.JTextField tfEdit;
    // End of variables declaration//GEN-END:variables
    //Hier beginnt der manuelle Code
    private CORE core;
    private JTable target;
    //Änderungen nachverfolgen--------------------------------------------------
    private int selTab = -1; //Aktive Tabelle
    private String selTabName = ""; //Name der aktiven Tablle
    private int selRow = -1; //Zeile der Änderung
    private int selCol = -1; //Spalte der Änderung
    private String old = ""; //Enthält den alten Wert der Zelle
    //--------------------------------------------------------------------------
    //Ende

    //Beginn des manuellen Code
    private void initData() {
        miUndo.setEnabled(false);
        miRedo.setEnabled(false);
        miSave.setEnabled(false);
        pEdit.setVisible(false);
        drawTables();
    }

    private void drawTables() {
        for (int i = 0; i < core.getVariable().getDataTable().size(); i++) {
            JTable t = core.getVariable().getDataTable().get(i).getAsTable();
            t = addML(t);
            t.getTableHeader().setReorderingAllowed(false);
            JScrollPane sp = new JScrollPane(t);
            maintp.addTab(core.getVariable().getDataTable().get(i).getTabName(), sp);
        }
    }

    private JTable addML(JTable t) {
        t.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    target = (JTable) e.getSource();
                    selTab = maintp.getSelectedIndex();
                    selRow = target.getSelectedRow();
                    selCol = target.getSelectedColumn();
                    target.setEnabled(false);
                    target.setFocusable(false);
                    maintp.setEnabled(false);
                    maintp.setFocusable(false);
                    editCell(selTab, selRow, selCol);
                }
            }
        });
        return t;
    }

    private void editCell(int t, int r, int c) {

        this.selTabName = core.getVariable().getDataTable().get(t).getTabName();
        this.old = core.getVariable().getDataTable().get(t).getDataAtPosition(r, c);
        tfEdit.setText(old);
        pEdit.setVisible(true);
        lStatus.setText("Hinweis: Eintrag in Spalte " + (c + 1) + "/ Zeile" + (r + 1) + " der Tabelle \"" + selTabName + "\", wird editiert.");
    }

    private void modify() {

        //Weil nun editiert wird, können eventuelle Undo's nicht mehr rückgängig
        //gemacht werden. Deshalb wird die Redoliste gecleared------------------
        miRedo.setEnabled(false);
        if (core.getVariable().getRedo() != null || !core.getVariable().getRedo().isEmpty()) {
            core.getVariable().getRedo().clear();
        }
        //----------------------------------------------------------------------
        Object[] o = core.getVariable().getDataTable().get(selTab).getColHeader();
        String s1 = (String) o[selCol];
        Alteration alt = new Alteration(selTab, selTabName, selRow, s1, selCol, old, tfEdit.getText());
        core.getVariable().addAlt(alt);
        miUndo.setEnabled(true);
        miSave.setEnabled(true);
        core.getVariable().getDataTable().get(selTab).setDataAtPosition(tfEdit.getText(), selRow, selCol);
        maintp.removeAll();
        drawTables();
        lStatus.setText("Hinweis: Änderungsantrag wurde registriert! (Speichern am Ende nicht vergessen!)");
        System.out.println("Änderungslistelänge " + core.getVariable().getAlt().size());
    }

    private void endConnection() {
        try {
            core.getVariable().getCon().close();
        } catch (SQLException ex) {
            Logger.getLogger(MainWin.class.getName()).log(Level.SEVERE, null, ex);
            lStatus.setText("Fehler: Datenbankverbindung konnte nicht beendet werden! " + ex);
        }
    }

    private void saveToDB() {
        UpdateTable updateDB = new UpdateTable(core.getVariable(), this);
        core.getVariable().getAlt().clear();
        miUndo.setEnabled(false);
        miRedo.setEnabled(false);
        miSave.setEnabled(false);
    }

    public void setStatus(String txt) {
        lStatus.setText(txt);
        this.validate();
    }

    private void doUndo() {
        int i = (core.getVariable().getAlt().size() - 1);
        this.selTab = core.getVariable().getAlt().get(i).getTableNr();
        this.selRow = core.getVariable().getAlt().get(i).getRow();
        this.selCol = core.getVariable().getAlt().get(i).getColumn();
        this.old = core.getVariable().getAlt().get(i).getOldentry();
        //Eintrag in Redoliste setzen
        core.getVariable().setRedo(core.getVariable().getAlt().get(i));
        //Tabelle aktualisieren
        core.getVariable().getDataTable().get(selTab).setDataAtPosition(old, selRow, selCol);
        maintp.removeAll();
        drawTables();
        //Eintrag in Änderungsliste entfernen
        core.getVariable().getAlt().remove(i);
        //Sollte das der letzte Änderungs-Eintrag gewesen sein: Undo deaktivieren
        if (core.getVariable().getAlt() == null || core.getVariable().getAlt().isEmpty()) {
            miUndo.setEnabled(false);
        }
        //Durch den Undo: Redo wieder aktivieren
        miRedo.setEnabled(true);
        System.out.println("Änderungslistelänge " + core.getVariable().getAlt().size());
    }

    private void doRedo() {
        int i = (core.getVariable().getRedo().size() - 1);
        this.selTab = core.getVariable().getRedo().get(i).getTableNr();
        this.selRow = core.getVariable().getRedo().get(i).getRow();
        this.selCol = core.getVariable().getRedo().get(i).getColumn();
        this.old = core.getVariable().getRedo().get(i).getNewEntry();
        //Redo-Eintrag wieder der Änderungsliste hinzufügen
        core.getVariable().addAlt(core.getVariable().getRedo().get(i));
        //Tabelle aktualisieren
        core.getVariable().getDataTable().get(selTab).setDataAtPosition(old, selRow, selCol);
        maintp.removeAll();
        drawTables();
        //Eintrag in Änderungsliste entfernen
        core.getVariable().getRedo().remove(i);
        //Sollte das der letzte Redo-Eintrag gewesen sein: Redo-Menüpunkt deaktivieren
        if (core.getVariable().getRedo() == null || core.getVariable().getRedo().isEmpty()) {
            miRedo.setEnabled(false);
        }
        //Durch den Redo: Undo wieder aktivieren
        miUndo.setEnabled(true);
        System.out.println("Änderungslistelänge " + core.getVariable().getAlt().size());
    }

    private void saveToCSV() {
        SaveCSV csv = new SaveCSV(core.getVariable(), this);
    }

    private void printTest(int i) {
        this.selTab = i;
        MessageFormat header = new MessageFormat("Tabelle: " + core.getVariable().getDataTable().get(selTab).getTabName());
        MessageFormat footer = new MessageFormat("Seite - {0}");
        JScrollPane sp = (JScrollPane) maintp.getComponentAt(0);
        JTable t = (JTable) sp.getViewport().getComponent(0);
        try {
            boolean complete = t.print(PrintMode.FIT_WIDTH, header, footer);
            if (complete) {
                lStatus.setText("Tabelle " + core.getVariable().getDataTable().get(selTab).getTabName() + " wurde gedruckt");
            } else {
                lStatus.setText("Hinweis: Drucken der Tabelle " + core.getVariable().getDataTable().get(selTab).getTabName() + " wurde abgebrochen");
            }
        } catch (PrinterException pe) {
            lStatus.setText("Fehler: Der Druckvorgang konnte nicht korrekt durchgeführt werden! " + pe.getMessage());
        }
    }

    private void closeProgram() {
        if (!core.getVariable().getAlt().isEmpty()) {
            int i = -1;
            Object[] options = {"Ja, in der Datenbank",
                "Ja, als CSV",
                "Abbrechen"};
            i = JOptionPane.showOptionDialog(this,
                    "Möchten Sie vor dem Beenden die Änderungen noch speichern?",
                    "HC-Connect",
                    JOptionPane.YES_NO_CANCEL_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    options,
                    options[0]);

            if (i == 0) {
                saveToDB();
                endConnection();
                this.dispose();
                System.exit(0);
            } else if (i == 1) {
                saveToCSV();
                endConnection();
                this.dispose();
                System.exit(0);
            } else if (i == 2) {
            }
        } else {
            endConnection();
            this.dispose();
            System.exit(0);
        }
    }
}
